package com.hyacinth.server.handler;

import com.alibaba.fastjson.JSON;
import com.hyacinth.server.action.response.AuroraResponse;
import com.hyacinth.server.action.response.WrapMapper;
import com.hyacinth.server.action.response.Wrapper;
import com.hyacinth.server.context.AuroraContext;
import com.hyacinth.server.exception.AuroraException;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Function:
 *
 * @author crossoverJie
 *         Date: 2018/8/30 18:47
 * @since JDK 1.8
 */
@ChannelHandler.Sharable
public final class HttpDispatcher extends SimpleChannelInboundHandler<DefaultHttpRequest> {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpDispatcher.class);

    /** 单实例 **/
    static final HttpDispatcher INSTANCE = new HttpDispatcher();

    /**
     * 读取http请求，完成响应
     * @param ctx 上下文
     * @param httpRequest http请求
     */
    @Override
    public void channelRead0(ChannelHandlerContext ctx, DefaultHttpRequest httpRequest) {

    }

    /**
     * 异常捕获
     * @param ctx 上下文
     * @param cause 异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        String errMsg = cause.getMessage();
        if (AuroraException.isResetByPeer(errMsg)) {
            LOGGER.warn("服务端抛出异常:{}","Connection reset by peer");
            return;
        }
        // 打印异常信息
        LOGGER.error(errMsg, cause);
        // 封装异常响应
        Wrapper<Object> wrap = WrapMapper.wrap(HttpResponseStatus.NOT_FOUND.code(), errMsg);
        // 创建默认响应
        DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, Unpooled.copiedBuffer(JSON.toJSONString(wrap), CharsetUtil.UTF_8));
        // 构建响应头
        buildHeader(response);
        // 写入
        ctx.writeAndFlush(response);
    }

    /**
     * 构建响应头
     * @param response 响应
     */
    private void buildHeader(DefaultFullHttpResponse response) {

        AuroraResponse auroraResponse = AuroraContext.getResponse();

        HttpHeaders headers = response.headers();
        headers.setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
        headers.set(HttpHeaderNames.CONTENT_TYPE, auroraResponse.getContentType());

    }


    public static void main(String[] args) {
        Wrapper<Object> wrap = WrapMapper.wrap(HttpResponseStatus.NOT_FOUND.code(), "this is ,,,,,,");
        System.out.println(JSON.toJSONString(wrap));
    }
}
